# send_to_powermeter.py
from __future__ import with_statement
import time, sys, httplib, urllib, logging, os, traceback
import simplejson as json
import google_meter, units
import credentials, common

READINGS = '/var/www/readings.json'
#READINGS = 'readings.json'
USER = 'mshook'
USER = 'cgswh'
VARIABLE_PATH = credentials.powermeter_variable(USER)[:-1]
TOKEN = credentials.powermeter_token(USER)
INTERVAL_SECONDS = 30 
UPLOAD_INTERVAL_SECONDS = 10 * 60
#UPLOAD_INTERVAL_SECONDS = 1 * 60
os.chdir('/home/dms/roque')
common.setup_logging()

#print TOKEN
service = google_meter.Service(TOKEN)
service = google_meter.BatchAdapter(service)

# watts = [0.0]*25

def get_readings():
    with open(READINGS, 'r') as f:
        l = f.read().encode()
    try:
        readings = json.loads(l)
        readings['ok'] = True
    except:
        logging.debug('json failure: '+"'"+l+"'")
        readings = {u'datetime': time.ctime(),
                    'ok': False,
                    u'volts': 0.0,
                    u'watts1': 0.0, u'watts2': 0.0,
                    u'raw': ["0"]*32}
        traceback.print_exc()
    return readings

def upload_readings(readings, variable, initial):
    now = time.time()
    print now, time.ctime()
    for i in range(len(readings)):
        circuit_variable = variable + str(i+1)
        event = google_meter.InstMeasurement(circuit_variable, now, readings[i] * units.JOULE,
                                             0.1, 0.0001 * units.KILOWATT_HOUR, initial)
        if i < 24:
            service.PostEvent(event)
            # print i, readings[i] * units.JOULE
    #for event in service.events:
    #    print event.ToXml()
    try:
        service.Flush()
    except:
        print 'Flush() error'
        traceback.print_exc()
        logging.debug('Flush() error')


time.sleep(5) # make sure that get_readings.py has written readings.json
prev_readings = get_readings()
prev_watts = prev_readings[u'watts']

print json.dumps(prev_readings)

cumulative_joules = [0.0]*24
upload_readings(cumulative_joules, VARIABLE_PATH, True)

next_upload = time.time() + UPLOAD_INTERVAL_SECONDS

run = True
initial = False
while run:
    time.sleep(INTERVAL_SECONDS)
    readings = get_readings()
    if readings['ok']:
        watts = readings[u'watts']
        curr_time = time.mktime(time.strptime(readings[u'datetime']))
        prev_time = time.mktime(time.strptime(prev_readings[u'datetime']))
        interval_seconds = curr_time - prev_time
        if interval_seconds > 1000000.0:
        # This may happen if OS time is finally set by NTP and is no longer 1970.
        # I *think* this will avoid PowerMeter displaying what
        # looks like a huge surge.
            initial = True
        print interval_seconds
        if interval_seconds > 0.0:
            for i in range(24):
                # avg_watts = ((readings[u'watts'][i]+prev_readings[u'watts'][i])/2)
                avg_watts = (watts[i]+prev_watts[i])/2
                cumulative_joules[i] += avg_watts * interval_seconds
            prev_readings = readings.copy()
            prev_watts = prev_readings[u'watts']
            if time.time() > next_upload:
                next_upload = time.time() + UPLOAD_INTERVAL_SECONDS
                upload_readings(cumulative_joules, VARIABLE_PATH, initial)
                initial = False
